home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / Kibitz / CMRookMate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  7.4 KB  |  323 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        cmrookmate.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20.  
  21.  
  22. /*****************************************************************************/
  23.  
  24.  
  25.  
  26. extern short    gPieceLoc;
  27.  
  28.  
  29.  
  30. /*****************************************************************************/
  31. /*****************************************************************************/
  32.  
  33. #ifdef applec
  34. #pragma segment Chess
  35. #endif
  36.  
  37. /*****************************************************************************/
  38. /*****************************************************************************/
  39.  
  40.  
  41.  
  42. short    RookMate(FileRecHndl game)
  43. {
  44.     short            color, myKingLoc, opKingLoc, pieceLoc;
  45.     short            mkr, mkc, okr, okc, pr, pc;
  46.     short            dr, dc, absdr, absdc;
  47.     short            from, to, minVal, minMove;
  48.     short            rspin;
  49.     Boolean            hflip, onEdge;
  50.     MoveListHndl    moves;
  51.     short            num, move;
  52.  
  53.     GenerateLegalMoves(game);
  54.     num   = (*game)->doc.numLegalMoves;
  55.     moves = (*game)->doc.legalMoves;
  56.  
  57.     color = WhosMove(game);
  58.     myKingLoc = (*game)->doc.king[color].kingLoc;
  59.     opKingLoc = (*game)->doc.king[1 - color].kingLoc;
  60.     pieceLoc  = gPieceLoc;
  61.  
  62.     GetDeltas(myKingLoc, pieceLoc, &dr, &dc, &absdr, &absdc);
  63.     if ((absdr > 1) || (absdc > 1)) {            /* If piece not next to king... */
  64.         GetRowCol(opKingLoc, &okr, &okc);
  65.         onEdge = false;
  66.         if ((!okr) || (okr == 7)) onEdge = true;
  67.         if ((!okc) || (okc == 7)) onEdge = true;
  68.         for (minVal = 16, move = 0; move < num; ++move) {
  69.             from = (**moves)[move].moveFrom;
  70.             to   = (**moves)[move].moveTo;
  71.             if (from == pieceLoc) {            /* If piece move... */
  72.                 GetDeltas(to, opKingLoc, &dr, &dc, &absdr, &absdc);
  73.                 if ((onEdge) && (absdr < 3) && (absdc < 3)) continue;
  74.                     /* We don't want to stalemate the guy while trying to get
  75.                     ** our piece close to our king. */
  76.                 if ((absdr < 2) && (absdc < 2)) continue;
  77.                     /* We don't want to get our piece captured either. */
  78.                 GetDeltas(to, myKingLoc, &dr, &dc, &absdr, &absdc);
  79.                 if (minVal > (absdr + absdc)) {
  80.                     minVal = absdr + absdc;
  81.                     minMove = move;
  82.                 }
  83.             }
  84.         }
  85.         return(minMove);
  86.     }
  87.  
  88.     for (rspin = 0;; ++rspin) {        /* Rotate until opponent king is above us. */
  89.         GetDeltas(myKingLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  90.         if (dr > 1) break;
  91.         RSpinPosition(&myKingLoc);
  92.         RSpinPosition(&opKingLoc);
  93.         RSpinPosition(&pieceLoc);
  94.     }
  95.         
  96.     GetDeltas(myKingLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  97.     hflip = false;
  98.     if (dc < 0) hflip = true;        /* Position opponent king left of ours. */
  99.     if (!dc) {
  100.         GetDeltas(pieceLoc, opKingLoc, &dr, &dc, &absdr, &absdc);
  101.         if (dc < 0) hflip = true;
  102.     }
  103.     if (hflip) {
  104.         HFlipPosition(&myKingLoc);
  105.         HFlipPosition(&opKingLoc);
  106.         HFlipPosition(&pieceLoc);
  107.     }
  108.  
  109.     GetRowCol(myKingLoc, &mkr, &mkc);
  110.     GetRowCol(opKingLoc, &okr, &okc);
  111.     GetRowCol(pieceLoc,  &pr,  &pc);
  112.  
  113.     from = pieceLoc;        /* Default that we will move the piece. */
  114.     switch (myKingLoc - pieceLoc) {
  115.         case -11:
  116.             if (mkc < 2) {        /* myKing too close to left edge. */
  117.                 to = (from = myKingLoc) + 1;
  118.                 break;
  119.             }
  120.             to = from - 20;        /* opKing at least 2 rows above, so cut it off. */
  121.             break;
  122.         case -10:
  123.             if (mkc < 2) {        /* myKing too close to left edge. */
  124.                 to = (from = myKingLoc) + 1;
  125.                 break;
  126.             }
  127.             if (mkc == 7) {        /* myKing on right edge, so move piece left. */
  128.                 to = from - 1;
  129.                 break;
  130.             }
  131.             if (mkc - okc < 2) {    /* opKing above or just 1 left, so move piece right */
  132.                 to = from + 1;        /* to prevent opKing from getting away. */
  133.                 break;
  134.             }
  135.             to = from - 1;        /* opKing left of us enough to cut it off on the */
  136.             break;                /* left side of myKing. */
  137.         case -9:
  138.             if (mkc == okc) {    /* opKing is above myKing. */
  139.                 to = from + 2;    /* Cut the king off from moving right. */
  140.                 break;
  141.             }
  142.             to = from - 10;        /* opKing is 2 rows above myKing, so just slide the piece up. */
  143.             break;
  144.         case -1:
  145.             if (mkr == 7) {        /* myKing on bottom edge, so move piece up. */
  146.                 to = from - 10;
  147.                 break;
  148.             }
  149.             to = from - 10;        /* opKing at least 2 rows above myKing, so move piece up. */
  150.             break;
  151.         case 1:
  152.             if (mkc == okc) {        /* If opKing is above us, we punt. */
  153.                 if (mkr == 7) {
  154.                     to = from - 10;        /* If at bottom, move piece up 1. */
  155.                     break;
  156.                 }
  157.                 to = from + 10;            /* Move piece down 1. */
  158.                 break;
  159.             }
  160.             if ((mkr == 2) && (mkc == 2)) {        /* Leads to mate in 1 or 2 for rook. */
  161.                 to = (from = myKingLoc) - 10;
  162.                 break;
  163.             }
  164.             if ((mkr > 2) || (mkc == 2)) {
  165.                 if ((mkr + okr) & 0x01) {
  166.                     to = (from = myKingLoc) - 10;
  167.                     break;
  168.                 }
  169.             }
  170.             to = from - 10;
  171.             break;
  172.         case 9:
  173.             if ((mkc == 1) && (!okc)) {
  174.                 to = from - 1;
  175.                 break;
  176.             }
  177.             if (!mkc) {            /* myKing on left edge. */
  178.                 to = (from = myKingLoc) + 1;
  179.                 break;
  180.             }
  181.             if (mkc == okc) {
  182.                 if ((mkr - okr) == 2) {
  183.                     to = (from = myKingLoc) + 1;
  184.                     break;
  185.                 }
  186.                 if ((mkr - okr) > 2) {
  187.                     to = (from = myKingLoc) - 10;
  188.                     break;
  189.                 }
  190.             }
  191.             to = from - 1;
  192.             if (mkc - okc > 1) --to;
  193.             break;
  194.         case 10:
  195.             if ((mkr == 2) && (mkc == 2)) {
  196.                 if (mkr == 2) {            /* Leads to mate in 1 or 2 for rook. */
  197.                     to = (from = myKingLoc) - 1;
  198.                     break;
  199.                 }
  200.             }
  201.             if ((mkr == 3) && (mkc == 2)) {
  202.                 if ((okr == 1) && (okc == 1)) {
  203.                     to = (from = myKingLoc) - 9;
  204.                     break;
  205.                 }
  206.                 if (!okr) {
  207.                     to = (from = myKingLoc) - 11;
  208.                     break;
  209.                 }
  210.                 to = from - 1;
  211.                 break;
  212.             }
  213.             if (mkc < 2) {        /* myKing too close to left edge. */
  214.                 to = (from = myKingLoc) + 1;
  215.                 if (mkr > 2) to -= 10;
  216.                 break;
  217.             }
  218.             if ((mkc - okc) == 1) {
  219.                 to = (from = myKingLoc) - 1;
  220.                 if ((mkr - okr) > 2) to -= 10;
  221.                 break;
  222.             }
  223.             to = from - 1;
  224.             break;
  225.         case 11:
  226.             if ((mkr == 2) && (mkc == 2)) {
  227.                 to = from + 10;
  228.                 break;
  229.             }
  230.             if (mkc == okc) {
  231.                 to = from + 1;
  232.                 if (mkc < 7) ++to;
  233.                 break;
  234.             }
  235.             if (mkc > 2) {
  236.                 to = (from = myKingLoc) - 1;
  237.                 break;
  238.             }
  239.             to = (from = myKingLoc) - 10;
  240.             break;
  241.     }
  242.  
  243.     if (hflip) {
  244.         HFlipPosition(&from);
  245.         HFlipPosition(&to);
  246.     }
  247.  
  248.     for (; rspin < 4; ++rspin) {        /* Rotate some more to make 4. */
  249.         RSpinPosition(&from);
  250.         RSpinPosition(&to);
  251.     }
  252.         
  253.     for (move = 0; move < num; ++move)
  254.         if ((from == (**moves)[move].moveFrom) && (to == (**moves)[move].moveTo)) return(move);
  255.  
  256.     return(-1);
  257.         
  258. }
  259.  
  260.  
  261.  
  262. /*****************************************************************************/
  263.  
  264.  
  265.  
  266. void    GetRowCol(short pos, short *row, short *col)
  267. {
  268.     *row = (pos - START_IBNDS) / 10;
  269.     *col = pos - START_IBNDS - *row * 10;
  270. }
  271.  
  272.  
  273.  
  274. /*****************************************************************************/
  275.  
  276.  
  277.  
  278. void    GetDeltas(short pos1, short pos2, short *dr, short *dc, short *absdr, short *absdc)
  279. {
  280.     short    r1, c1, r2, c2;
  281.  
  282.     GetRowCol(pos1, &r1, &c1);
  283.     GetRowCol(pos2, &r2, &c2);
  284.     *dr = r1 - r2;
  285.     *dc = c1 - c2;
  286.  
  287.     if ((*absdr = *dr) < 0) *absdr = -*absdr;
  288.     if ((*absdc = *dc) < 0) *absdc = -*absdc;
  289. }
  290.  
  291.  
  292.  
  293. /*****************************************************************************/
  294.  
  295.  
  296.  
  297. void    RSpinPosition(short *pos)
  298. {
  299.     short    oldr, oldc, newr, newc;
  300.  
  301.     GetRowCol(*pos, &oldr, &oldc);
  302.     newr = oldc;
  303.     newc = 7 - oldr;
  304.     *pos = START_IBNDS + 10 * newr + newc;
  305. }
  306.  
  307.  
  308.  
  309. /*****************************************************************************/
  310.  
  311.  
  312.  
  313. void    HFlipPosition(short *pos)
  314. {
  315.     short    r, c;
  316.  
  317.     GetRowCol(*pos, &r, &c);
  318.     *pos = START_IBNDS + 10 * r + (7 - c);
  319. }
  320.  
  321.  
  322.  
  323.